<template>
	<el-container>
		<el-main class="nopadding">
			<div class="tablet-content">
				<el-row :gutter="8">
					<el-col :span="14">
						<el-card class="tablet-card" header="生产数据">
							<el-table :data="workTableData" class="tablet-table">
								<el-table-column prop="sn" label="SN" width="180" />
								<el-table-column prop="status" label="状态" width="100">
									<template #default="scope">
										<el-tag type="success" v-if="scope.row.status === 1"> OK </el-tag>
										<el-tag type="danger" v-else-if="scope.row.status === 2"> NG </el-tag>
										<el-tag type="Warning" v-else>OK</el-tag>
									</template>
								</el-table-column>
								<el-table-column prop="inboundTime" label="进站时间" width="160" />
								<el-table-column prop="outboundTime" label="出站时间" />
							</el-table>
						</el-card>
					</el-col>
					<el-col :span="10">
						<el-card class="tablet-card" header="日志消息">
							<el-table :data="logTableData" class="tablet-table">
								<el-table-column prop="time" label="时间" width="140" />
								<el-table-column prop="message" label="消息">
									<template #default="scope">
										<div :style="{ display: 'flex', color: scope.row._color }">
											{{ scope.row.message }}
										</div>
									</template>
								</el-table-column>
							</el-table>
						</el-card>
					</el-col>
				</el-row>
			</div>
		</el-main>
	</el-container>
</template>

<script setup lang="ts">
import { ref, onMounted, getCurrentInstance } from 'vue';
import * as signalR from "@microsoft/signalr";

const instance = getCurrentInstance();
const proxy2 = {
	proxy: instance?.proxy,
	globalProp: instance!.appContext.config.globalProperties,
};

const props = defineProps({
	lineCode: { type: String },
	opCode: { type: String },
});

const mode = {
	inbound: '产品进站',
	outbound: '产品出站',
	scanbarcode: '扫关键物料',
	scanbatch: '扫批次料',
	feeding: '上料',
};
let connection: signalR.HubConnection;
const workTableData = ref<any>([]);
const logTableData = ref<any>([]);

onMounted(async () => {
	await init();
	await start();
})

async function init() {
	const token = proxy2.globalProp.$TOOL.data.get("TOKEN");
	connection = new signalR.HubConnectionBuilder()
		.withUrl(proxy2.globalProp.$CONFIG.SignalR_Channel_URL, {
			accessTokenFactory: () => token,
		})
		.configureLogging(signalR.LogLevel.Error)
		// .withAutomaticReconnect() // 分别等待 0、2、10 和 30 秒, 第四次尝试失败后，停止尝试重新连接
		.build();

	// 连接断开后自动重连
	// 自动连接下，在其前四次尝试中未成功重新连接，会触发 onclose 回调。
	connection.onclose(async () => {
		await start();
	});

	// 接收服务端指定的消息（有指定产线+工位）
	connection.on("ReceiveMessage", args => {
		console.log('signalr args', args);
		// 解析参数，非此工位跳过
		if (args.lineCode !== props.lineCode || args.opCode !== props.opCode) {
			return;
		}

		receiveMessage(args);
	});
}

async function start() {
	try {
		if (connection) {
			await connection.start();
			console.log('signalr connection ok');
		}
	} catch (err) {
		setTimeout(start, 10000); // 10s 后重试
	}
}

function receiveMessage(args: any) {
	// 消息
	setLogData(args);

	// 数据
	setWorkData(args);
}

function setWorkData(args: any) {
	// 作业只记录 "进站" 和 "出站" 数据
	if (args.mode !== 'inbound' || args.mode !== 'outbound') {
		return;
	}

	const data = {
		sn: args.sn,
		status: 0, // 1->OK；2->NG；3->报废
		inboundTime: 0,
		outboundTime: 0,
	};
	if (args.mode === 'inbound') {
		data.status === 0;
		data.inboundTime === 0;
	} else if (args.mode === 'outbound') {
		const target = args.target;
		data.outboundTime === target?.outboundTime;
	}

	workTableData.value.unshift(data); // 追加到开头

	// 超过长度后移除末尾
	if (workTableData.value.length > 64) {
		workTableData.value.pop();
	}
}

function setLogData(args: any) {
	const modeDesc = mode[args.mode] ?? '';
	const msg = `[${args.innerErrorCode}] ${modeDesc}--${args.errorMessage}`;
	const data = {
		time: proxy2.globalProp.$TOOL.dateFormat(args.time, 'MM/dd HH:mm:ss'),
		message: msg,
		_color: args.innerErrorCode ? 'red' : '',
	};
	logTableData.value.unshift(data); // 追加到开头

	// 超过长度后移除末尾
	if (logTableData.value.length > 64) {
		logTableData.value.pop();
	}
}
</script>

<style lang="scss" scoped>
.tablet-content {
	height: 100%;
	margin: 0 4px; // 用于抵消 el-row.gutter 产生的水平滚动条
}

.tablet-card {
	height: 98%;
}

.tablet-content :deep(.el-row) {
	height: 100%;
}

.tablet-card>:deep(.el-card__body) {
	height: 100%;
}

.tablet-table {
	height: calc(100% - 35px);
}
</style>
